{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Balanced Network De-embedding"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Demonstration of *balanced*, i.e. 2N-port, network  de-embedding."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import skrf as rf\n",
    "from skrf.media import CPW\n",
    "\n",
    "rf.stylely()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# base parameters\n",
    "freq = rf.Frequency(1e-3,10,1001,'ghz')\n",
    "cpw  = CPW(freq, w=0.6e-3, s=0.25e-3, ep_r=10.6, z0_port=50)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build fixture network\n",
    "* short length of mismatched line with connector-like input shunt capacitance\n",
    "* some crosstalk added with nudge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "             l1\n",
    "    0----+-=======-2\n",
    "         |\n",
    "         = c1\n",
    "         |\n",
    "        GND\n",
    "\n",
    "             l1\n",
    "    1----+-=======-3\n",
    "         |\n",
    "         = c1\n",
    "         |\n",
    "        GND\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "l1 = cpw.line(20, unit='mm')\n",
    "c1 = cpw.shunt_capacitor(C=0.15e-12)\n",
    "l1 = rf.connect(c1, 1, l1, 0)\n",
    "li = rf.concat_ports([l1, l1], port_order='second')\n",
    "Fix = li\n",
    "Fix.name = 'Fix'\n",
    "Fix.nudge(1e-4)\n",
    "Left = Fix\n",
    "# flip fixture for right side\n",
    "Right = Fix.flipped()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build DUT network\n",
    "\n",
    "* some length of mismatched lines\n",
    "* some crosstalk added with nudge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "        l2\n",
    "    0-=======-2\n",
    "        l2\n",
    "    1-=======-3\n",
    "\"\"\"\n",
    "l2 = cpw.line(50, 'mm')\n",
    "DUT = rf.concat_ports([l2, l2], port_order='second')\n",
    "DUT.name = 'DUT'\n",
    "DUT.nudge(1e-5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build the measurement\n",
    "\n",
    "* cascade Left, DUT and Right\n",
    "* add some noise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "            Left        Meas         Right\n",
    "             l1          l2           l1\n",
    "    0----+-=======-2 0-=======-2 0-=======-+----2\n",
    "         |                                 |\n",
    "         = c1                              = c1\n",
    "         |                                 |\n",
    "        GND                               GND\n",
    "\n",
    "             l1          l2           l1\n",
    "    1----+-=======-3 1-=======-3 1-=======-+----3\n",
    "         |                                 |\n",
    "         = c1                              = c1\n",
    "         |                                 |\n",
    "        GND                               GND\n",
    "\"\"\"\n",
    "Meas = Left ** DUT ** Right\n",
    "Meas.name = 'Meas'\n",
    "Meas.add_noise_polar(1e-5, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Perform de-embedding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "DUTd = Left.inv ** Meas ** Right.inv\n",
    "DUTd.name = 'DUTd'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Display results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "fig, axarr = plt.subplots(2,2, sharex=True, figsize=(10,6))\n",
    "\n",
    "ax = axarr[0,0]\n",
    "Meas.plot_s_db(m=0, n=0, ax=ax)\n",
    "DUTd.plot_s_db(m=0, n=0, ax=ax)\n",
    "DUT.plot_s_db(m=0, n=0, ax=ax, ls=':', color='0.0')\n",
    "ax.set_title('Return Loss')\n",
    "ax.legend(loc='lower center', ncol=3)\n",
    "ax.grid(True)\n",
    "\n",
    "ax = axarr[0,1]\n",
    "Meas.plot_s_db(m=2, n=0, ax=ax)\n",
    "DUTd.plot_s_db(m=2, n=0, ax=ax)\n",
    "DUT.plot_s_db(m=2, n=0, ax=ax, ls=':', color='0.0')\n",
    "ax.set_title('Insertion Loss')\n",
    "ax.legend(loc='lower center', ncol=3)\n",
    "ax.grid(True)\n",
    "\n",
    "ax = axarr[1,0]\n",
    "Meas.plot_s_db(m=1, n=0, ax=ax)\n",
    "DUTd.plot_s_db(m=1, n=0, ax=ax)\n",
    "DUT.plot_s_db(m=1, n=0, ax=ax, ls=':', color='0.0')\n",
    "ax.set_title('Isolation')\n",
    "ax.legend(loc='lower center', ncol=3)\n",
    "ax.grid(True)\n",
    "\n",
    "ax = axarr[1,1]\n",
    "Meas.plot_s_deg(m=2, n=0, ax=ax)\n",
    "DUTd.plot_s_deg(m=2, n=0, ax=ax, marker='o', markevery=25)\n",
    "DUT.plot_s_deg(m=2, n=0, ax=ax, ls=':', color='0.0')\n",
    "ax.set_title('Insertion Loss')\n",
    "ax.legend(loc='lower center', ncol=3)\n",
    "ax.grid(True)\n",
    "\n",
    "fig.tight_layout()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
